package com.randi.system.service.impl.sysNotice;

import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageInfo;
import com.randi.common.constant.CacheConstants;
import com.randi.common.core.domain.entity.SysUser;
import com.randi.common.utils.SecurityUtils;
import com.randi.common.utils.page.PageHelperUtils;
import com.randi.system.domain.dto.NoticeBody;
import com.randi.system.domain.entity.sysNotice.SysNotice;
import com.randi.system.domain.entity.sysNotice.SysNoticePush;
import com.randi.system.domain.params.SysNoticeParam;
import com.randi.system.domain.params.SysUserParam;
import com.randi.system.domain.vo.SysNoticeInfo;
import com.randi.system.domain.vo.SysNoticeUser;
import com.randi.system.mapper.sysNotice.SysNoticeMapper;
import com.randi.system.service.ISysUserService;
import com.randi.system.service.sysNotice.ISysNoticePushService;
import com.randi.system.service.sysNotice.ISysNoticeReadService;
import com.randi.system.service.sysNotice.ISysNoticeService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author ziye
 */
@Service
@CacheConfig(cacheNames = CacheConstants.SYS_NOTICE)
public class SysNoticeServiceImpl implements ISysNoticeService {

    @Resource
    private SysNoticeMapper sysNoticeMapper;

    @Resource
    private ISysNoticePushService iSysNoticePushService;

    @Resource
    private ISysNoticeReadService iSysNoticeReadService;

    @Resource
    private ISysUserService iSysUserService;

    /**
     * 分页查询业务列表
     *
     * @param sysNoticeParam sysNoticeType
     * @return 业务集合
     */
    @Override
    @Cacheable(keyGenerator = "baseKeyGenerator", unless = "#result == null")
    public PageInfo<SysNotice> selectPageList(SysNoticeParam sysNoticeParam) {
        PageHelperUtils.initPage(sysNoticeParam);
        return new PageInfo<>(sysNoticeMapper.selectSysNoticeList(sysNoticeParam));
    }

    /**
     * 查看详情
     *
     * @return 业务集合
     */
    @Override
    @Cacheable(key = "#noticeId", unless = "#result == null")
    public SysNoticeInfo selectSysNoticeById(Long noticeId) {
        SysNoticeInfo sysNoticeInfo = new SysNoticeInfo(sysNoticeMapper.selectSysNoticeById(noticeId));
        List<Long> readUserIds = iSysNoticeReadService.selectSysNoticeReadUserIds(noticeId);
        List<SysNoticeUser> sysNoticeUsers;

        if (sysNoticeInfo.getPushRange() == 0) {
            if (readUserIds.isEmpty()) {
                sysNoticeUsers = Collections.emptyList();
            } else {
                SysUserParam sysUserParam = new SysUserParam();
                sysUserParam.setIncludes(readUserIds);
                sysNoticeUsers = iSysUserService.selectSysUserList(sysUserParam).stream().map(user -> {
                    SysNoticeUser sysNoticeUser = JSON.parseObject(JSON.toJSONString(user), SysNoticeUser.class);
                    sysNoticeUser.setRead(true);
                    return sysNoticeUser;
                }).collect(Collectors.toList());
            }
        } else {
            // 使用 ConcurrentHashMap 确保线程安全
            Map<Long, Boolean> readMap = new ConcurrentHashMap<>();
            readUserIds.forEach(userId -> readMap.put(userId, Boolean.TRUE));
            List<SysUser> sysUsers = iSysNoticePushService.selectUserList(noticeId);
            sysNoticeUsers = sysUsers.stream()
                    .map(user -> {
                        SysNoticeUser sysNoticeUser = JSON.parseObject(JSON.toJSONString(user), SysNoticeUser.class);
                        sysNoticeUser.setRead(readMap.containsKey(user.getUserId()));
                        return sysNoticeUser;
                    })
                    .collect(Collectors.toList());
        }

        sysNoticeInfo.setReadTotal(readUserIds.size());
        sysNoticeInfo.setUsers(sysNoticeUsers);
        return sysNoticeInfo;
    }

    /**
     * 插入数据
     *
     * @param noticeBody sysNotice
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true, beforeInvocation = true)
    public int insertSysNotice(NoticeBody noticeBody) {
        SysNotice sysNotice = noticeBody.toEntity();
        SecurityUtils.setInsertInfo(sysNotice);
        int status = sysNoticeMapper.insert(sysNotice);

        if (status == 0) {
            return 0;
        }


        List<Long> userIds = noticeBody.getUserIds();
        if (sysNotice.getPushRange() == 0 || userIds == null || userIds.isEmpty()) {
            return 1;
        }

        // 推送用户
        List<SysNoticePush> sysNoticePushList = userIds.stream()
                .map(userId -> new SysNoticePush(sysNotice.getNoticeId(), userId))
                .collect(Collectors.toList());
        return iSysNoticePushService.batchInsertSysNoticePush(sysNoticePushList);
    }

    /**
     * 更新数据
     *
     * @param sysNotice SysNotice
     * @return 结果
     */
    @Override
    @CacheEvict(allEntries = true, beforeInvocation = true)
    public int updateSysNotice(SysNotice sysNotice) {
        SecurityUtils.setUpdateInfo(sysNotice);
        return sysNoticeMapper.updateById(sysNotice);
    }

    /**
     * 删除数据
     *
     * @param noticeId noticeId
     * @return 结果
     */
    @Override
    @CacheEvict(allEntries = true, beforeInvocation = true)
    public int deleteSysNotice(Long noticeId) {
        List<Long> noticeIds = Collections.singletonList(noticeId);
        return this.deleteBatchSysNotice(noticeIds);
    }

    /**
     * 批量删除数据
     *
     * @param noticeIds noticeIds
     * @return status
     */
    @Override
    @CacheEvict(allEntries = true, beforeInvocation = true)
    public int deleteBatchSysNotice(List<Long> noticeIds) {
        return sysNoticeMapper.batchUpdateDeleted(noticeIds);
    }

}
